
/**
 * @(#)ConnectFourBoard.java
 *
 *
 * @author
 * @version 1.00 2012/3/8
 */

import java.awt.*;
import javax.swing.Timer;
import java.awt.event.MouseEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.Rectangle;

import javax.swing.*;

public class ConnectFourBoard extends GameBoard {

	int[][] currentState;
	ConnectFourCore core;
	Timer t;
	int time;
	Boolean Remove;
    boolean flip=true;


    public ConnectFourBoard(int row, int col, int res,Boolean flip, Boolean remove, int timeLimit)
    {
    	super(row,col,res);
    	currentState = new int[row][col];
    	core = new ConnectFourCore(currentState,1);
    	time=timeLimit;
    	Remove=remove;
    	
    	//instantiate the timer
    	if(time!=0)
    	{
	    	ActionListener task = new ActionListener()
	    			{
		    			public void actionPerformed(ActionEvent evt) 
		    			{
		    				int loser=core.GetCurrentPlayer();
		    				if(loser==1)
		    					winnerWindow(2,true);
		    				else
		    					winnerWindow(1,true);
		    			}
	    			};
	    			
	    	t=new Timer(timeLimit,task);
	    	t.setRepeats(false);
    	}
    	//add mouse listener
    	addMouseListener(this);
    	
    }

    @Override public void paintComponent(Graphics g)
    {
    	super.paintComponent(g);
    	Graphics2D g2 = (Graphics2D)g;
    	
		int paneWidth = super.getWidth();
		int paneHeight = super.getHeight();
		int rowHeight = paneHeight/super.Rows;
		int colWidth = paneWidth/super.Columns;


    	//Draw board based on state
		Rectangle rect = new Rectangle(0,0,super.Resolution*super.Columns,super.Resolution*super.Rows);
		g2.draw(rect);
		g2.setPaint(Color.yellow);
		g2.fill(rect);
    	for(int i=0;i<currentState.length;i++) {
    		for(int j=0;j<currentState[i].length;j++) {
    			switch(currentState[i][j]) {
    				case 1: g2.setColor(Color.red); break;
    				case 2: g2.setColor(Color.black); break;
    				default: g2.setColor(Color.gray); break;
    			}
    			g2.fillOval(j*colWidth,i*rowHeight, super.Resolution-7, super.Resolution-7);
    			g2.setColor(Color.black);
    			g2.draw(new Ellipse2D.Double(j*colWidth,i*rowHeight, super.Resolution-7, super.Resolution-7));
    		}
    	}
    	
    	
    }

    public void setState(int[][] s)
    {
    	flip=true;
    	currentState = s;
    	this.repaint();
    	if(core.HasWon()==1)
    		winnerWindow(core.GetCurrentPlayer(),false);

    }
    public void winnerWindow(int winnerInt, Boolean timeloss)
    {
    	
    	removeMouseListener(this);
    	
    	//did the player lose by running out of time?
		String display;
		if(winnerInt==3)
			display= "The game is a Tie!";
		else if(timeloss==false)
			display= "Player "+Integer.toString(winnerInt)+" has won!";
		else 
		{
			//stop timer
	    	t.stop();
			display="Player "+Integer.toString(winnerInt)+" has won (by time limit)!";
		}
		
		JOptionPane.showMessageDialog(this, display, "Winner", JOptionPane.INFORMATION_MESSAGE);
		
    	//game logic for playing again
    	Object[] options = {"Yes",
        "No"};

		int n = JOptionPane.showOptionDialog(this,
				"Would you like to play again?",
						"Play Again?",
						JOptionPane.YES_NO_OPTION,
						JOptionPane.QUESTION_MESSAGE,
						null,
						options,
						options[1]);
		if(n==1)
		{
			System.exit(0);
		}
		else
		{
			this.setVisible(false);
			new SizingWindow();
		}

    }

    //Mouse Listener Events
    public void mouseClicked(MouseEvent e)
    {
    		if((e.getY()>=super.getHeight()-super.Resolution) && Remove && currentState[currentState.length-1][currentState[0].length * e.getX()/super.getWidth()]==core.GetCurrentPlayer() )
    		{
    			core.Remove(currentState[0].length * e.getX()/super.getWidth());
    			setState(core.GetCurrentState());
    			/*int [][] temp = core.GetCurrentState();
    			int col = tree.buildTree(temp);
    			core.Drop(col);
    			setState(core.GetCurrentState());*/
    			if(time!=0)
    	    	{
    	    		//restart the timer if move is made within
    	    		//the time limit
    	    		t.stop();
    	    		t.start();
    	    	}
    			return;
    		}
	    	core.Drop(currentState[0].length * e.getX()/super.getWidth());
	    	setState(core.GetCurrentState());
	    	//if time==0 there is no time limit
	    	if(time!=0)
	    	{
	    		//restart the timer if move is made within
	    		//the time limit
	    		t.stop();
	    		t.start();
	    	}
	    	/*int [][] temp = core.GetCurrentState();
			int col = tree.buildTree(temp);
			core.Drop(col);
			setState(core.GetCurrentState());*/
	    	MinmaxTree tree = new MinmaxTree(core);
	    	System.out.println(tree.determineMove(2));
	    	core.Drop(tree.determineMove(2));
	    	setState(core.GetCurrentState());
	    	
    }
    
    public void Flip()
    {
    	if(flip)
    	{
	    	core.Flip();
	    	setState(core.GetCurrentState());
	    	if(time!=0)
	    	{
	    		t.stop();
	    		t.start();
	    	}
    	}
    	flip=false;
    }
    
     

}